﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//int add(int a, int b)
//	{
//		return a + b;
//	}
//int sub(int a, int b)
//	{
//		return a - b;
//	}
//int mul(int a, int b)
//	{
//		return a * b;
//	}
//int div(int a, int b)
//	{
//		return a / b;
//	}
//void cavl(int(*pf)(int, int))
//{
//	int x = 0;
//	int y = 0;
//	printf("请输入数字\n");
//	scanf("%d %d", &x, &y);
//	int r = 0;
//	r = pf(x, y);
//	printf("%d\n", r);
//}
//
//int main()
//{
//	int input = 0;
//	do
//	{
//		printf("************************* \n");
//		printf(" 1:add              2:sub \n");
//		printf(" 3:mul              4:div \n");
//		printf("************************* \n");
//		printf("请输入:\n");
//		scanf("%d", &input);
//		switch (input)
//		{
//		case 1:
//			cavl(add);
//			break;
//		case 2:
//			cavl(sub);
//			break;
//		case 3:
//			cavl(mul);
//			break;
//		case 4:
//			
//			cavl(div);
//			break;
//		default:
//			printf("输入错误\n");
//			break;
//		}
//	} while (input);
//	return 0;
//}
#include <stdlib.h>
#include <string.h>
//struct Stu //学⽣
//{
//	char name[20];//名字
//	int age;//年龄
//};
////假设按照年龄来⽐较
//int cmp_stu_by_age(const void* e1, const void* e2)
//{
//	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//}
////strcmp - 是库函数，是专⻔⽤来⽐较两个字符串的⼤⼩的
////假设按照名字来⽐较
//int cmp_stu_by_name(const void* e1, const void* e2)
//{
//	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
//}
////按照年龄来排序
//void test2()
//{
//	struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
//	int sz = sizeof(s) / sizeof(s[0]);
//	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
//	printf("按年龄排序:\n");
//	for (int i = 0; i < sz; i++) {
//		printf("%s %d\n", s[i].name, s[i].age);
//	}
//}
////按照名字来排序
//void test3()
//{
//	struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
//	int sz = sizeof(s) / sizeof(s[0]);
//		qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
//}
//int main()
//{
//	test2();
//	
//	test3();
//	return 0;
//}

//struct Stu
//{
//	char name[20];
//	int age;
//};
//int cmp_stu_by_name(const void*p1,const void*p2)
//{
//	return strcmp(((struct Stu*)p1)->name,((struct Stu*)p2)->name);//强制转换类型
//}
//void test2()
//{
//	struct Stu s[] = { {"zhangsan",20},{"list",30},{"wangwu",15} };
//	int sz = sizeof(s) / sizeof(s[0]);
//	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);//比较名字
//	printf("按年龄排序:\n");
//	for (int i = 0; i < sz; i++) {
//		printf("%s %d\n", s[i].name, s[i].age);
//	}
//}
//int main()
//{
//	test2();
//	return 0;
//}


#include <stdio.h>
//int main()
//{
//	char arr1[3] = { 'a', 'b', 'c' };
//	char arr2[] = "abc";
//	printf("%d\n", strlen(arr1));
//	printf("%d\n", strlen(arr2));//strlen计算的是字符串长度，有\0则停止
//	printf("%d\n", sizeof(arr1));
//	printf("%d\n", sizeof(arr2));//sizeof计算的是字符串大小，里面有什么就计算什么；
//	return 0;
//}
//int main()
//{
//	int a[] = { 1,2,3,4 };
//	printf("%d\n", sizeof(a));//16
//	printf("%d\n", sizeof(a + 0));// 4/8
//	printf("%d\n", sizeof(*a));// 4/8
//	printf("%d\n", sizeof(a + 1));//4/8
//	printf("%d\n", sizeof(a[1]));//4/8
//	printf("%d\n", sizeof(&a));//4/8
//	printf("%d\n", sizeof(*&a));//16
//	printf("%d\n", sizeof(&a + 1));//4/8
//	printf("%d\n", sizeof(&a[0]));//4/8
//	printf("%d\n", sizeof(&a[0] + 1));//4/8
//	return 0;
//}


//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };
//	printf("%d\n", sizeof(arr));//6
//	printf("%d\n", sizeof(arr + 0));//计算的是指针的大小，为4/8
//	printf("%d\n", sizeof(*arr));//1
//	printf("%d\n", sizeof(arr[1]));//1
//	printf("%d\n", sizeof(&arr));//4/8
//	printf("%d\n", sizeof(&arr + 1));//4/8
//	printf("%d\n", sizeof(&arr[0] + 1));//4/8
//	return 0;
//}


#include <string.h>
//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f','\0'};//strlen() 必须接收 '\0' 结尾的字符串，否则是未定义行为。
//	printf("%zu\n", strlen(arr));
//	printf("%zu\n", strlen(arr + 0));
//	printf("%zu\n", strlen((char*)arr)); 
//	printf("%d\n", strlen((char*)&arr[1]));//arr[1]是字符，不是地址，不能转为char*;
//	printf("%d\n", strlen((char*) & arr));
//	printf("%d\n", strlen((char*) & arr + 1));
//	printf("%zu\n", strlen(&arr[0] + 1));
//		return 0;
//}

//int main()
//{
//	char arr[] = "abcdef";
//	printf("%d\n", strlen(arr));//6
//	printf("%d\n", strlen(arr + 0));//6
//	printf("%d\n", strlen((char*)arr));//6
//	printf("%d\n", strlen((char*)&arr[1]));//5
//	printf("%d\n", strlen((char*)&arr));//6
//	printf("%d\n", strlen((char*)&arr + 1));//5
//	printf("%d\n", strlen(&arr[0] + 1));//5
//	return 0;
//}
//数组
//int cmp_by(void*p1, void*p2)
//{
//	return(*(int*)p2 - *(int*)p1);
//}
//void Swap(char* buf1, char* buf2, size_t width)
//{
//	//进行交换
//	int i = 0;
//	char tmp = 0;
//	for (i = 0; i < width; i++)
//	{
//		tmp = *buf1;
//		*buf1 = *buf2;
//		*buf2 = tmp;
//		*buf1++;
//		*buf2++;
//	}
//}
//void bubble(void* base, int sz, int width, int(* cmp)(void*,void*))
//{
//	//进行交换
//	int i = 0;
//	for (i = 0; i < sz - 1; i++)
//	{
//		int j = 0;
//		for (j = 0; j < sz - i - 1; j++)
//		{//进行比较
//			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
//			{
//				//进行交换，写一个函数说明
//				Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
//			}
//		}
//	}
//
//}
//void print(int arr[],int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//}
//void test1()
//{
//	int arr[] = { 2,3,4,6,5,7,9,8,0,1 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	print(arr,sz);
//	bubble(arr, sz, sizeof(arr[0]), cmp_by);
//	print(arr,sz);
//}
//
//int main()
//{
//	//创建一个需要排序的数组
//	test1();
//	return 0;
//}

//结构体
#include <assert.h>
//struct Stu
//{
//	char name[20];//要写上20，否则为指针无法对char使用char*
//	int age;
//};
//int cmp_by( void* p1, void* p2)
//{
//	/*assert(p1, p2);*/
//	return strcmp(((struct Stu*)p1)->name,((struct Stu*)p2)->name);
//}
//void Swap(char* buf1, char* buf2, size_t width)
//{
//	//进行交换
//	int i = 0;
//	char tmp = 0;
//	for (i = 0; i < width; i++)
//	{
//		tmp = *buf1;
//		*buf1 = *buf2;
//		*buf2 = tmp;
//		
//		*buf1++;
//		*buf2++;
//	}
//}
//void bubble(void* base, int sz, int width, int(*cmp)(void*, void*))
//{
//	//进行交换
//	int i = 0;
//	for (i = 0; i < sz - 1; i++)
//	{
//		int j = 0;
//		for (j = 0; j < sz - i - 1; j++)
//		{//进行比较
//			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
//			{
//				//进行交换，写一个函数说明
//				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
//			}
//		}
//	}
//
//}
//void print(struct Stu s[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%s %d ",s[i].name,s[i].age);//结构体打印
//	}
//	printf("\n");
//}
//
//
//void test1()
//{
//	struct Stu s[] = { {"zhangsan",20},{"lisi",22},{"lixinag",33} };
//	int sz = sizeof(s) / sizeof(s[0]);
//	print(s, sz);
//	bubble(s, sz, sizeof(s[0]), cmp_by);
//	print(s, sz);
//}
//
//int main()
//{
//	//创建一个需要排序的数组
//	test1();
//	return 0;
//}




//int main()	
//{
//	char arr[] = "abcdef";
//	printf("%zu\n", strlen(arr));//6
//	printf("%zu\n", strlen(arr + 0));//6
//	//printf("%d\n", strlen(*arr));//地址非法
//	//printf("%d\n", strlen(arr[1]));//取出来一个数，错误
//	printf("%zu\n", strlen((char*) & arr));//1
//	printf("%zu\n", strlen((char*)( & arr + 1)));//随机值，，要概括全部起来
//	printf("%zu\n", strlen(&arr[0] + 1));//5
//	return 0;
//}


//int main()
//{
//	const char* p = "abcdef";
//	printf("%d\n", sizeof(p));//4/8,第一个的地址
//	printf("%d\n", sizeof(p + 1));//4/8
//	printf("%d\n", sizeof(*p));//1
//	printf("%d\n", sizeof(p[0]));//1
//	printf("%d\n", sizeof(&p));//4/8
//	printf("%d\n", sizeof(&p + 1));//4/8
//	printf("%d\n", sizeof(&p[0] + 1));//4/8
//	return 0;
//}




//int main()
//{
//	int a[3][4] = { 0 };
//	printf("%d\n", sizeof(a));//48
//	printf("%d\n", sizeof(a[0][0]));//4/8
//    printf("%d\n", sizeof(a[0]));//16
//	printf("%d\n", sizeof(a[0] + 1));//4/8//第一行第二个元素的地址
//	printf("%d\n", sizeof(*(a[0] + 1)));//4/8
//	printf("%d\n", sizeof(a + 1));//4/8第一行的地址；加一为第二行的地址，地址为4/8个字节 
//	printf("%d\n", sizeof(*(a + 1)));//*（a+1）等价于a[1]第二行的数组名为16
//	printf("%d\n", sizeof(&a[0] + 1));//4/8地址
//	printf("%d\n", sizeof(*(&a[0] + 1)));//16第二行的地址
//	printf("%d\n", sizeof(*a));//16
//	printf("%d\n", sizeof(a[3]));//越界也是一样。
//	return 0;
//}


//int main()
//{
//	int a[5] = { 1, 2, 3, 4, 5 };
//	int* ptr = (int*)(&a + 1);
//	printf("%d,%d", *(a + 1), *(ptr - 1));
//	return 0;
//}

//在X86环境下 1
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥？
//在x64是32
//struct Test
//{
//	int Num;
//	char* pcName;
//	short sDate;
//	char cha[2];
//	short sBa[4];
//}*p = (struct Test*)0x100000;//结构体加指针为结构体指针 
//int main()
//{
//	printf("%p\n", p + 0x1);
//	printf("%p\n", (unsigned long)p + 0x1);//整数加一就是加一
//	printf("%p\n", (unsigned int*)p + 0x1);//整型4个字节
//	printf("Size: %zu bytes\n", sizeof(unsigned long));
//	return 0;
//}


//int main()
//{
//	int a[3][2] = { (0, 1), (2, 3), (4, 5) };//逗号表达式按最后一个算，且最后一个问题没用{}，不是初始化数组
//	int* p;
//	p = a[0];
//	printf("%d", p[0]);//1
//	return 0;
//}

//int main()
//{
//	int a[5][5];
//	int(*p)[4];
//	p = a;
//	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//	return 0;
//}
//int main()
//{
//	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//	int* ptr1 = (int*)(&aa + 1);
//	int* ptr2 = (int*)(*(aa + 1));
//	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10 5
//	return 0;
//}
//
//int main()
//{
//    const char* a[] = { "work","at","alibaba" };
//	const char** pa = a;//二级指针存放地址，pa++为第二个字符
//	pa++;
//	printf("%s\n", *pa);//at解引用
//	return 0;
//}


//int main()
//{
//	const char* c[] = { "ENTER","NEW","POINT","FIRST" };
//	const char** cp[] = { c + 3,c + 2,c + 1,c };
//	const char*** cpp = cp;
//	printf("%s\n", **++cpp);//POINT
//	printf("%s\n", *-- * ++cpp + 3);//上一个已经++了，改变过一次，解引用之后为c+1,-1为c,
//	printf("%s\n", *cpp[-2] + 3);//数组*（cpp-2）
//		printf("%s\n", cpp[-1][-1] + 1);//*（*（cpp-1）-1）+1//ew
//	return 0;
//}



//int main()
//{
//	int a[5][5];
//	int(*p)[4];
//	p = a;
//	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//	return 0;
//}

int main()
{
	int a =-4;
	printf("%p ", a);
	return 0;
}